package com.xiaoluo.lottery.service;

import com.xiaoluo.lottery.dao.PlayRecordJdbcDao;
import com.xiaoluo.lottery.dao.PlayerJdbcDao;
import com.xiaoluo.lottery.dao.RoundJdbcDao;
import com.xiaoluo.lottery.entity.PlayRecord;
import com.xiaoluo.lottery.entity.Player;
import com.xiaoluo.lottery.entity.Round;
import com.xiaoluo.lottery.exception.LotteryException;
import com.xiaoluo.lottery.filter.PlayRecordFilter;
import com.xiaoluo.lottery.vo.DataPage;
import com.xiaoluo.lottery.vo.PlayRecordVo;
import com.xl.tool.current.DCSCASKit;
import com.xl.tool.redis.FastJsonKit;
import com.xl.tool.redis.JedisResource;
import com.xl.tool.redis.RedisKit;
import com.xl.tool.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by Caedmon on 2016/4/5.
 */
@Service
public class PlayerServiceImpl implements PlayerService{
    @Autowired
    private PlayerJdbcDao playerJdbcDao;
    @Autowired
    private PlayRecordJdbcDao playRecordJdbcDao;
    @Autowired
    private RoundJdbcDao roundJdbcDao;
    @Autowired
    private OnlineNumManager onlineNumManager;
    public static final String PLAYER_LOCK_PREFIX="player_lock_";
    public static final String PLAYER_KEY_PREFIX="player_";
    private static final Logger log= LoggerFactory.getLogger(PlayerServiceImpl.class);
    @Override
    public Player getPlayer(String openId) {
        Player player=RedisKit.get(PLAYER_KEY_PREFIX+openId);
        if(player==null){
            player=playerJdbcDao.getPlayer(openId);
            int weekSeconds=(int)DateUtil.WEEK_MILLS/1000;
            RedisKit.setex(PLAYER_KEY_PREFIX+openId, weekSeconds,player);
        }
        if(player==null){
            throw LotteryException.build("用户不存在");
        }
        return player;
    }

    @Override
    public Player savePlayer(Player player) {
        //判断是否已存在
        try{
            getPlayer(player.getOpenId());
            player.setUpdateAt(new Date());
            playerJdbcDao.updatePlayer(player);
            int weekSeconds=(int)DateUtil.WEEK_MILLS/1000;
            RedisKit.setex(PLAYER_KEY_PREFIX+player.getOpenId(), weekSeconds,player);
        }catch (LotteryException e){
            if(e.getError().equals("用户不存在")){
                player.setCreateAt(new Date());
                playerJdbcDao.createPlayer(player);
                int weekSeconds=(int)DateUtil.WEEK_MILLS/1000;
                RedisKit.setex(PLAYER_KEY_PREFIX+player.getOpenId(), weekSeconds,player);
            }else{
                throw e;
            }

        }
        return player;
    }

    @Override
    public DataPage<PlayRecordVo> getPlayerRecords(PlayRecordFilter filter) {
        DataPage<PlayRecord> page= playRecordJdbcDao.findRecords(filter);
        Jedis jedis=JedisResource.getInstance().get();
        String[] roundIdArray=new String[page.getContentSize()];
        for(int i=0;i<page.getContentSize();i++){
            PlayRecord record=page.getContent().get(i);
            roundIdArray[i]=RoundServiceImpl.ROUND_CACHE_KEY_PREFIX+record.getRoundId();
        }
        List<PlayRecordVo> result=new ArrayList<>();
        if(roundIdArray.length!=0){
            List<String> list=jedis.mget(roundIdArray);
            for(int i=0;i<page.getContentSize();i++){
                PlayRecord record=page.getContent().get(i);
                String roundString=list.get(i);
                Round round=null;
                if(StringUtils.isEmpty(roundString)){
                    round=roundJdbcDao.get(record.getRoundId());
                }else{
                    round=FastJsonKit.jsonToJava(roundString, Round.class);
                }
                if(round==null){
                    continue;
                }
                PlayRecordVo vo=new PlayRecordVo();
                vo.setRecord(record);
                vo.setRoundName(round.getName());
                vo.setRoundCreateOpenId(round.getCreatePlayerOpenId());
                Player createPlayer=getPlayer(round.getCreatePlayerOpenId());
                vo.setRoundCreateNickName(createPlayer.getNickName());
                vo.setRoundCreateHeadImage(createPlayer.getHeadImage());
                vo.setRoundStatus(round.getStatus());
                vo.setRoundCreateAt(round.getCreateAt());
                vo.setRoundTotalAmount(round.getTotalAmount());
                String winnerOpenId=round.getWinnerOpenId();
                if(!StringUtils.isEmpty(winnerOpenId)){
                    vo.setRoundWinnerOpenId(winnerOpenId);
                    Player winner=getPlayer(winnerOpenId);
                    vo.setRoundWinnerNickName(winner.getNickName());
                    vo.setRoundWinnerHeadImage(winner.getHeadImage());
                }
                result.add(vo);
            }
        }

        return new DataPage<>(result,page.getTotal(),page.getPageIndex(),page.getPageSize());
    }
    public  static String getPlayerLockKey(String openId){
        return PLAYER_LOCK_PREFIX+openId;
    }
    @Override
    public double updateBalance(String openId,double amount) {
        DCSCASKit.lock(getPlayerLockKey(openId),1000);
        try{
            Player player=getPlayer(openId);
            if(amount<0&&player.getBalance()<-amount){
             throw new LotteryException("余额不足");
            }
            player.setBalance(player.getBalance()+amount);
            savePlayer(player);
            log.info("Update player balance:openId={},amount={},balance={}",openId,amount,player.getBalance());
        }finally {
            DCSCASKit.unlock(getPlayerLockKey(openId));
        }
        return 0;
    }
    @Override
    public int getOnlineNum() {
        return onlineNumManager.getPubNum();
    }
}
